import json
import time
import asyncio
from datetime import datetime
from fastapi import APIRouter, HTTPException, Depends
from sqlalchemy.orm import Session
from sqlalchemy import func

from common.models import NetLetterRequest, LetterResponse
from common.database import get_db, NetRecord, get_storage_adapter
from common.config import MAX_TEXT_LENGTH, SUMMARY_TARGET_LENGTH
from common.long_context_summary import async_map_reduce_summarize
from net.services.case_processor import CaseProcessor
from net.net_logger import log_api_request, log_api_response, log_error
from net.utils.async_utils import async_log_error

# 创建路由器
router = APIRouter(prefix="/api", tags=["信访件处理"])

# 全局变量，需要在主应用中初始化
CALL_RECORDS = {}
thread_pool = None
case_processor = None


def set_global_variables(_call_records, _thread_pool):
    """设置全局变量，由主应用调用"""
    global CALL_RECORDS, thread_pool, case_processor
    CALL_RECORDS = _call_records
    thread_pool = _thread_pool
    case_processor = CaseProcessor(_thread_pool)


@router.post("/getNetLetters", response_model=LetterResponse)
async def get_letters(
    request: NetLetterRequest,
):
    """处理网络信访件请求"""
    try:
        # 记录开始时间
        start_time = time.time()

        # 检查文本长度，如果超过阈值则进行摘要处理
        original_length = len(request.caseIntruction)
        processed_content = request.caseIntruction
        
        if original_length > MAX_TEXT_LENGTH:
            print(f"文本长度 {original_length} 超过阈值 {MAX_TEXT_LENGTH}，开始进行摘要处理...")
            try:
                processed_content = await async_map_reduce_summarize(
                    request.caseIntruction, 
                    target_length=SUMMARY_TARGET_LENGTH
                )
                print(f"摘要处理完成，长度从 {original_length} 压缩到 {len(processed_content)}")
            except Exception as e:
                print(f"摘要处理失败: {e}")
                # 如果摘要失败，截断到最大长度
                processed_content = request.caseIntruction[:MAX_TEXT_LENGTH]
                print(f"使用截断文本，长度: {len(processed_content)}")
        else:
            print(f"文本长度 {original_length} 在阈值范围内，无需摘要处理")

        # 实时记录调用请求到内存
        CALL_RECORDS[request.bh] = {
            "bh": request.bh,
            "ysbh": getattr(request, "ysbh", None),
            "startTime": datetime.fromtimestamp(start_time).strftime(
                "%Y-%m-%d %H:%M:%S"
            ),
            "status": "处理中",
            "processTime": 0,
            "requestInfo": request.dict(),  # 存储请求的字典形式
            "responseInfo": None,
            "errorInfo": None,
        }

        # 使用存储适配器创建记录（使用处理后的文本）
        storage = get_storage_adapter()
        db_record = storage.create_net_record(
            bh=request.bh,
            ysbh=getattr(request, "ysbh", None),
            start_time=datetime.fromtimestamp(start_time),
            status="处理中",
            case_instruction=processed_content,
            fyrs=json.dumps(request.fyrs, ensure_ascii=False) if request.fyrs else None,
            cfj=json.dumps(request.cfj, ensure_ascii=False) if request.cfj else None,
            bfyrs=(
                json.dumps(request.bfyrs, ensure_ascii=False) if request.bfyrs else None
            ),
        )

        # 记录API请求到日志
        await log_api_request_async(request.bh, request.dict(), start_time)

        # 准备请求参数（使用处理后的文本）
        case_content = processed_content
        bfyrs_json = None
        cfj_json = None

        # 只有当bfyrs不为空时才添加到请求参数中
        if request.bfyrs and len(request.bfyrs) > 0:
            bfyrs_json = json.dumps(request.bfyrs, ensure_ascii=False)

        # 只有当cfj不为空时才添加到请求参数中
        if request.cfj and len(request.cfj) > 0:
            cfj_json = json.dumps(request.cfj, ensure_ascii=False)

        try:
            # 调用异步处理函数（使用处理后的文本）
            result = await case_processor.process_case_async(
                request.bh,
                case_content,
                bfyrs_json,
                cfj_json,
                getattr(request, "ysbh", None),
            )

            # 计算处理时间
            processing_time = time.time() - start_time

            # 实时更新CALL_RECORDS中的成功信息
            if request.bh in CALL_RECORDS:
                CALL_RECORDS[request.bh]["status"] = "成功"
                CALL_RECORDS[request.bh]["responseInfo"] = result  # 存储响应的字典形式
                CALL_RECORDS[request.bh][
                    "processTime"
                ] = processing_time  # 直接存储秒数

            # 更新存储记录
            storage.update_net_record(
                request.bh,
                status="成功",
                response=json.dumps(result, ensure_ascii=False),
                process_time=processing_time
            )

            # 记录API响应到日志
            await log_api_response_async(request.bh, result, processing_time)

            return {"bh": request.bh, "success": "true", "message": "", "data": result}

        except Exception as e:
            error_msg = f"处理过程中发生错误: {str(e)}"
            # 实时更新CALL_RECORDS中的失败信息
            if request.bh in CALL_RECORDS:
                CALL_RECORDS[request.bh]["status"] = "失败"
                CALL_RECORDS[request.bh]["errorInfo"] = {"message": error_msg}

            # 更新存储记录为失败
            storage.update_net_record(
                request.bh,
                status="失败",
                error_info=error_msg
            )

            await async_log_error(request.bh, error_msg)
            raise HTTPException(status_code=500, detail=error_msg)

    except Exception as e:
        error_msg = f"API处理错误: {str(e)}"
        # 实时更新CALL_RECORDS中的失败信息
        if request.bh in CALL_RECORDS:
            CALL_RECORDS[request.bh]["status"] = "失败"
            CALL_RECORDS[request.bh]["errorInfo"] = {"message": error_msg}

        # 如果在存储记录创建前发生错误，则不会有 db_record，这里需要更谨慎处理
        if "db_record" in locals() and db_record:
            storage.update_net_record(
                request.bh,
                status="失败",
                error_info=error_msg
            )

        await async_log_error(request.bh, error_msg)
        raise HTTPException(status_code=500, detail=error_msg)


async def log_api_request_async(bh: str, request_data: dict, start_time: float):
    """异步记录API请求"""
    await asyncio.get_event_loop().run_in_executor(
        thread_pool, log_api_request, bh, request_data, start_time
    )


async def log_api_response_async(bh: str, response_data: dict, processing_time: float):
    """异步记录API响应"""
    await asyncio.get_event_loop().run_in_executor(
        thread_pool, log_api_response, bh, response_data, processing_time
    )
